import 'package:ding_rtc/ding_rtc.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';

import '../Constants.dart';
import '../models/user_model.dart';
import '../tool.dart';

class MeetingPage extends StatefulWidget {

  String meetingId;
  String userId;
  String userName;

  MeetingPage({required this.meetingId, required this.userId, required this.userName});

  @override
  State<MeetingPage> createState() => _MeetingPageState();
}

class _MeetingPageState extends State<MeetingPage> {

  DingRtcListener? _listener;
  //当前一屏显示出来的用户
  List _screenUserList = [];
  //总共在房间里的用户
  final List<UserModel> _userList = [];
  late UserModel currentUser;

  @override
  initState() {
    super.initState();
    currentUser = UserModel(userId: widget.userId);
    DingRtcEngine().setLogLevel(DingRtcLogLevel.DingRtcLogLevelNone);
    _initRoom();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      _initData();
    });
  }

  _initRoom() async {
    await DingRtcEngine().initEngine();
    _listener = DingRtcListener(
        onRemoteUserEnterRoom: _handleOnRemoteUserEnterRoom,
        onRemoteUserLeaveRoom: _handleOnRemoteUserLeaveRoom,
      onError: (code, message) {
        print('DingRtc onError: $code, $message');
        MeetingTool.toast('onError: $code, $message', context);
      },
      onEnterRoom: (result, userId) {
          print("DingRtc onEnterRoom: $result - $userId");
          MeetingTool.toast('Enter room success. $result', context);
      },
      onRemoteStateUpdated: (userId, audio, video) {
        print('DingRtc onRemoteStateUpdated: $userId, $audio, $video');
      },
    );
    DingRtcEngine().registerListener(_listener!);
    DingRtcEngine().enterRoom(DRTCParams(
        userId: widget.userId,
        token: Constants.token(widget.userId),
        appID: Constants.appid,
        meetingId: widget.meetingId,
        gslbServer: Constants.gslbServer,
        userName: widget.userName));
  }

  _initData() {
    _userList.add(currentUser);
    _screenUserList = MeetingTool.getScreenList(_userList);
    setState(() {});
  }

  @override
  void dispose() {
    super.dispose();
    DingRtcEngine().exitRoom();
    DingRtcEngine().unRegisterListener(_listener);
    DingRtcEngine().destroyEngine();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: WillPopScope(
        onWillPop: () async {
          DingRtcEngine().exitRoom();
          return true;
        },
        child: Stack(
          children: <Widget>[
            PageView.builder(
                physics: const ClampingScrollPhysics(),
                itemCount: _screenUserList.length,
                itemBuilder: (BuildContext context, index) {
                  List<UserModel> item = _screenUserList[index];
                  return Container(
                    width: MediaQuery.of(context).size.width,
                    height: MediaQuery.of(context).size.height,
                    color: const Color.fromRGBO(19, 41, 75, 1),
                    child: Wrap(
                      children: List.generate(
                        item.length,
                        (index) => LayoutBuilder(
                            key: ValueKey(item[index].userValueKey),
                            builder: (context, constraints) => _userItem(index, item)),
                      )
                    )
                  );
                }),
            _topSetting(),
            // _beautySetting(),
            _bottomSetting()
          ]
        )
      )
    );
  }

  Widget _topSetting() {
    return Align(
        alignment: Alignment.topCenter,
        child: Container(
          margin: EdgeInsets.only(top: MediaQuery.of(context).padding.top),
          height: 50.0,
          color: const Color.fromRGBO(200, 200, 200, 0.4),
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: <Widget>[
              IconButton(
                  icon: Icon(
                      currentUser.isSpeaker ? Icons.volume_up : Icons.hearing,
                      color: Colors.white,
                      size: 36.0),
                  onPressed: () async {
                    if (currentUser.isSpeaker) {
                      DingRtcEngine().enableSpeakerphone(false);
                    } else {
                      DingRtcEngine().enableSpeakerphone(true);
                    }
                    setState(() {
                      currentUser.isSpeaker = !currentUser.isSpeaker;
                    });
                  }),
              IconButton(
                  icon: const Icon(
                    Icons.camera_alt,
                    color: Colors.white,
                    size: 36.0,
                  ),
                  onPressed: () async {
                    DingRtcEngine().switchCamera();
                    setState(() {
                      currentUser.isFrontCamera = !currentUser.isFrontCamera;
                    });
                  }),
              Text(widget.meetingId,
                      style:
                          const TextStyle(fontSize: 20, color: Colors.white)),
                  TextButton(
                      style: TextButton.styleFrom(
                          backgroundColor: Colors.red,
                          textStyle: const TextStyle(color: Colors.white)),
                      onPressed: _showExitMeetingConfirmDialog,
                      child: const Text("Exit Meeting",
                          style: TextStyle(fontSize: 16.0)))
                ])));
  }

  Future<bool?> _showExitMeetingConfirmDialog() {
    return showDialog<bool>(
        context: context,
        builder: (context) {
          return AlertDialog(
              title: const Text("Tips"),
              content: const Text("Are you sure to exit the meeting?"),
              actions: <Widget>[
                TextButton(
                  child: const Text("Cancel"),
                  onPressed: () => Navigator.of(context).pop(),
                ),
                TextButton(
                    child: const Text("Confirm"),
                    onPressed: () {
                      Navigator.of(context).pop(true);
                      Navigator.pop(context);
                    })
              ]);
        });
  }

  Widget _bottomSetting() {
    return Align(
        alignment: Alignment.bottomCenter,
        child: Container(
          padding: const EdgeInsets.fromLTRB(0, 0, 0, 20),
          height: 70.0,
          color: const Color.fromRGBO(200, 200, 200, 0.4),
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: <Widget>[
              IconButton(
                  icon: Icon(
                    currentUser.isOpenMic ? Icons.mic : Icons.mic_off,
                    color: Colors.white,
                    size: 36.0,
                  ),
                  onPressed: () {
                    if (currentUser.isOpenMic) {
                      DingRtcEngine().muteLocalAudio(false);
                    } else {
                      DingRtcEngine().muteLocalAudio(true);
                    }
                    setState(() {
                      currentUser.isOpenMic = !currentUser.isOpenMic;
                    });
                  }),
              IconButton(
                  icon: Icon(
                    currentUser.isOpenCamera ? Icons.videocam : Icons.videocam_off,
                    color: Colors.white,
                    size: 36.0,
                  ),
                  onPressed: () {
                    if (currentUser.isOpenCamera) {
                      _userList[0].isOpenCamera = false;
                      DingRtcEngine().enableLocalVideo(false);
                    } else {
                      _userList[0].isOpenCamera = true;
                      DingRtcEngine().enableLocalVideo(true);
                    }
                    setState(() { });
                  }),
              // IconButton(
              //     icon: const Icon(
              //       Icons.face,
              //       color: Colors.white,
              //       size: 36.0,
              //     ),
              //     onPressed: () {
              //       this.setState(() {
              //         if (_meetModel.getUserInfo().isShowBeauty) {
              //           _meetModel.getUserInfo().isShowBeauty = false;
              //         } else {
              //           _meetModel.getUserInfo().isShowBeauty = true;
              //         }
              //       });
              //     }),
              IconButton(
                  icon: const Icon(
                    Icons.people,
                    color: Colors.white,
                    size: 36.0,
                  ),
                  onPressed: () async {
                    Navigator.pushNamed(context, '/memberList');
                  }),
              // IconButton(
              //   icon: const Icon(
              //     Icons.share_rounded,
              //     color: Colors.white,
              //     size: 36.0,
              //   ),
              //   onPressed: () {
              //     this._onShareClick();
              //   },
              // ),
              // SettingsPage(),
              // IconButton(
              //     icon: Icon(
              //       Icons.info,
              //       color: Colors.white,
              //       size: 36.0,
              //     ),
              //     onPressed: () {
              //       if (kIsWeb) {
              //         Navigator.pushNamed(context, '/testweb');
              //         return;
              //       }
              //       Navigator.pushNamed(context, '/test');
              //     }),
            ],
          ),
        ));
  }

  Widget _userItem(int index, List<UserModel> item) {
    Size size = MeetingTool.getViewSize(
        MediaQuery.of(context).size, _userList.length, index, item.length);
    double width = size.width;
    double height = size.height;

    ValueKey valueKey = ValueKey("${item[index].userId}${item[index].type}0");
    if (item[index].width > 0) {
      width = item[index].width.toDouble();
      height = item[index].height.toDouble();
    }

    return SizedBox(
      key: valueKey,
      height: height,
      width: width,
      child: Stack(
        key: valueKey,
        children: <Widget>[
          _renderView(item[index], valueKey, width, height),
          _videoVoice(item[index])
        ]
      )
    );
  }
  Widget _renderView(UserModel item, valueKey, width, height) {
    return GestureDetector(
        key: valueKey,
        behavior: HitTestBehavior.opaque,
        child: DingRtcVideoView(
            key: valueKey,
            hitTestBehavior: PlatformViewHitTestBehavior.transparent,
            onViewCreated: (viewId) async {
              if (item.userId == currentUser.userId) {
                await DingRtcEngine().startLocalPreview(viewId,currentUser.isFrontCamera);
                await DingRtcEngine().muteLocalAudio(currentUser.isOpenMic);
                setState(() {
                  currentUser.localViewId = viewId;
                });
              } else {
                DingRtcEngine().startRemoteView(item.userId, viewId);
              }
              item.localViewId = viewId;
            }));
  }

  /// The user name and sound are displayed on the video layer
  Widget _videoVoice(UserModel item) {
    return Positioned(
        left: 24.0,
        bottom: 80.0,
        child: Row(children: <Widget>[
          Text(
            item.userId == currentUser.userId ? "${item.userId}(me)" : item.userId,
            style: const TextStyle(color: Colors.white),
          ),
          Container(
              margin: const EdgeInsets.only(left: 10),
              child: const Icon(
                Icons.signal_cellular_alt,
                color: Colors.white,
                size: 20,
              ))
        ]));
  }

  _handleOnRemoteUserEnterRoom(String userId){
    print('DingRtc onRemoteUserEnterRoom: $userId');
    UserModel user = UserModel(userId: userId);
    user.isOpenCamera = false;
    _userList.add(user);

    _screenUserList = MeetingTool.getScreenList(_userList);
    setState(() {});
  }

  _handleOnRemoteUserLeaveRoom(userId, reason) {
    print('DingRtc onRemoteUserLeaveRoom: $userId, $reason');
    _userList.removeWhere((element) {
      return element.userId == userId;
    });
    _screenUserList = MeetingTool.getScreenList(_userList);
    setState(() {});
  }
}